/*
 * Academic License - for use in teaching, academic research, and meeting
 * course requirements at degree granting institutions only.  Not for
 * government, commercial, or other organizational use.
 *
 * rcond.c
 *
 * Code generation for function 'rcond'
 *
 */

/* Include files */
#include "rcond.h"
#include "rt_nonfinite.h"
#include "xzgetrf.h"
#include "rt_nonfinite.h"
#include <math.h>
#include <string.h>

/* Function Definitions */
double rcond(const double A[16])
{
  double b_A[16];
  double normA;
  double result;
  double s;
  int b_i;
  int b_j;
  int j;
  int jA;
  boolean_T exitg1;
  result = 0.0;
  normA = 0.0;
  j = 0;
  exitg1 = false;
  while ((!exitg1) && (j < 4)) {
    jA = j << 2;
    s = ((fabs(A[jA]) + fabs(A[jA + 1])) + fabs(A[jA + 2])) + fabs(A[jA + 3]);
    if (rtIsNaN(s)) {
      normA = rtNaN;
      exitg1 = true;
    } else {
      if (s > normA) {
        normA = s;
      }
      j++;
    }
  }
  if (!(normA == 0.0)) {
    int ipiv[4];
    memcpy(&b_A[0], &A[0], 16U * sizeof(double));
    xzgetrf(b_A, ipiv);
    jA = 3;
    int exitg2;
    do {
      exitg2 = 0;
      if (jA + 1 > 0) {
        if (b_A[jA + (jA << 2)] == 0.0) {
          exitg2 = 1;
        } else {
          jA--;
        }
      } else {
        double x[4];
        double ainvnm;
        int iter;
        int jump;
        int kase;
        ainvnm = 0.0;
        iter = 2;
        kase = 1;
        jump = 1;
        j = 0;
        x[0] = 0.25;
        x[1] = 0.25;
        x[2] = 0.25;
        x[3] = 0.25;
        int exitg3;
        do {
          exitg3 = 0;
          if (kase == 1) {
            int ix;
            for (b_j = 0; b_j < 4; b_j++) {
              int i;
              jA = b_j + (b_j << 2);
              i = 2 - b_j;
              for (b_i = 0; b_i <= i; b_i++) {
                ix = (b_j + b_i) + 1;
                x[ix] -= x[b_j] * b_A[(jA + b_i) + 1];
              }
            }
            for (b_j = 3; b_j >= 0; b_j--) {
              jA = b_j + (b_j << 2);
              x[b_j] /= b_A[jA];
              for (b_i = 0; b_i < b_j; b_i++) {
                ix = (b_j - b_i) - 1;
                x[ix] -= x[b_j] * b_A[(jA - b_i) - 1];
              }
            }
          } else {
            for (b_j = 0; b_j < 4; b_j++) {
              jA = b_j << 2;
              s = x[b_j];
              for (b_i = 0; b_i < b_j; b_i++) {
                s -= b_A[jA + b_i] * x[b_i];
              }
              x[b_j] = s / b_A[jA + b_j];
            }
            for (b_j = 3; b_j >= 0; b_j--) {
              int i;
              jA = b_j << 2;
              s = x[b_j];
              i = b_j + 2;
              for (b_i = 4; b_i >= i; b_i--) {
                s -= b_A[(jA + b_i) - 1] * x[b_i - 1];
              }
              x[b_j] = s;
            }
          }
          if (jump == 1) {
            double absrexk;
            double ainvnm_tmp;
            double b_ainvnm_tmp;
            s = fabs(x[0]);
            absrexk = fabs(x[1]);
            ainvnm_tmp = fabs(x[2]);
            b_ainvnm_tmp = fabs(x[3]);
            ainvnm = ((s + absrexk) + ainvnm_tmp) + b_ainvnm_tmp;
            if ((!rtIsInf(ainvnm)) && (!rtIsNaN(ainvnm))) {
              if (s > 2.2250738585072014E-308) {
                x[0] /= s;
              } else {
                x[0] = 1.0;
              }
              if (absrexk > 2.2250738585072014E-308) {
                x[1] /= absrexk;
              } else {
                x[1] = 1.0;
              }
              if (ainvnm_tmp > 2.2250738585072014E-308) {
                x[2] /= ainvnm_tmp;
              } else {
                x[2] = 1.0;
              }
              if (b_ainvnm_tmp > 2.2250738585072014E-308) {
                x[3] /= b_ainvnm_tmp;
              } else {
                x[3] = 1.0;
              }
              kase = 2;
              jump = 2;
            } else {
              exitg3 = 1;
            }
          } else if (jump == 2) {
            double absrexk;
            j = 0;
            s = fabs(x[0]);
            absrexk = fabs(x[1]);
            if (!(absrexk <= s)) {
              j = 1;
              s = absrexk;
            }
            absrexk = fabs(x[2]);
            if (!(absrexk <= s)) {
              j = 2;
              s = absrexk;
            }
            if (!(fabs(x[3]) <= s)) {
              j = 3;
            }
            iter = 2;
            x[0] = 0.0;
            x[1] = 0.0;
            x[2] = 0.0;
            x[3] = 0.0;
            x[j] = 1.0;
            kase = 1;
            jump = 3;
          } else if (jump == 3) {
            double absrexk;
            double ainvnm_tmp;
            double b_ainvnm_tmp;
            s = fabs(x[0]);
            absrexk = fabs(x[1]);
            ainvnm_tmp = fabs(x[2]);
            b_ainvnm_tmp = fabs(x[3]);
            ainvnm = ((s + absrexk) + ainvnm_tmp) + b_ainvnm_tmp;
            if (ainvnm <= x[0]) {
              x[0] = 1.0;
              x[1] = -1.3333333333333333;
              x[2] = 1.6666666666666665;
              x[3] = -2.0;
              kase = 1;
              jump = 5;
            } else {
              if (s > 2.2250738585072014E-308) {
                x[0] /= s;
              } else {
                x[0] = 1.0;
              }
              if (absrexk > 2.2250738585072014E-308) {
                x[1] /= absrexk;
              } else {
                x[1] = 1.0;
              }
              if (ainvnm_tmp > 2.2250738585072014E-308) {
                x[2] /= ainvnm_tmp;
              } else {
                x[2] = 1.0;
              }
              if (b_ainvnm_tmp > 2.2250738585072014E-308) {
                x[3] /= b_ainvnm_tmp;
              } else {
                x[3] = 1.0;
              }
              kase = 2;
              jump = 4;
            }
          } else if (jump == 4) {
            double absrexk;
            jA = j;
            j = 0;
            s = fabs(x[0]);
            absrexk = fabs(x[1]);
            if (!(absrexk <= s)) {
              j = 1;
              s = absrexk;
            }
            absrexk = fabs(x[2]);
            if (!(absrexk <= s)) {
              j = 2;
              s = absrexk;
            }
            if (!(fabs(x[3]) <= s)) {
              j = 3;
            }
            if ((fabs(x[jA]) != fabs(x[j])) && (iter <= 5)) {
              iter++;
              x[0] = 0.0;
              x[1] = 0.0;
              x[2] = 0.0;
              x[3] = 0.0;
              x[j] = 1.0;
              kase = 1;
              jump = 3;
            } else {
              x[0] = 1.0;
              x[1] = -1.3333333333333333;
              x[2] = 1.6666666666666665;
              x[3] = -2.0;
              kase = 1;
              jump = 5;
            }
          } else if (jump == 5) {
            s = 2.0 * (((fabs(x[0]) + fabs(x[1])) + fabs(x[2])) + fabs(x[3])) /
                3.0 / 4.0;
            if (s > ainvnm) {
              ainvnm = s;
            }
            exitg3 = 1;
          }
        } while (exitg3 == 0);
        if (ainvnm != 0.0) {
          result = 1.0 / ainvnm / normA;
        }
        if (rtIsNaN(result)) {
          boolean_T p;
          p = false;
          for (jA = 0; jA < 16; jA++) {
            if (p || rtIsNaN(b_A[jA])) {
              p = true;
            }
          }
          if (!p) {
            result = 0.0;
          }
        }
        exitg2 = 1;
      }
    } while (exitg2 == 0);
  }
  return result;
}

/* End of code generation (rcond.c) */
